home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gsht1.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  16.0 KB  |  579 lines

  1. /* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gsht1.c,v 1.2 2000/09/19 19:00:29 lpd Exp $ */
  20. /* Extended halftone operators for Ghostscript library */
  21. #include "memory_.h"
  22. #include "gx.h"
  23. #include "gserrors.h"
  24. #include "gsstruct.h"
  25. #include "gsutil.h"        /* for gs_next_ids */
  26. #include "gzstate.h"
  27. #include "gxdevice.h"        /* for gzht.h */
  28. #include "gzht.h"
  29.  
  30. /* Define the size of the halftone tile cache. */
  31. #define max_tile_bytes_LARGE 4096
  32. #define max_tile_bytes_SMALL 512
  33. #if arch_small_memory
  34. #  define max_tile_cache_bytes max_tile_bytes_SMALL
  35. #else
  36. #  define max_tile_cache_bytes\
  37.      (gs_debug_c('.') ? max_tile_bytes_SMALL : max_tile_bytes_LARGE)
  38. #endif
  39.  
  40. /* Imports from gscolor.c */
  41. void load_transfer_map(P3(gs_state *, gx_transfer_map *, floatp));
  42.  
  43. /* Forward declarations */
  44. private int process_spot(P4(gx_ht_order *, gs_state *,
  45.                 gs_spot_halftone *, gs_memory_t *));
  46. private int process_threshold(P4(gx_ht_order *, gs_state *,
  47.                  gs_threshold_halftone *, gs_memory_t *));
  48. private int process_threshold2(P4(gx_ht_order *, gs_state *,
  49.                   gs_threshold2_halftone *,
  50.                   gs_memory_t *));
  51. private int process_client_order(P4(gx_ht_order *, gs_state *,
  52.                 gs_client_order_halftone *, gs_memory_t *));
  53.  
  54. /* Structure types */
  55. public_st_halftone_component();
  56. public_st_ht_component_element();
  57.  
  58. /* GC procedures */
  59.  
  60. private 
  61. ENUM_PTRS_WITH(halftone_component_enum_ptrs, gs_halftone_component *hptr) return 0;
  62. case 0:
  63. switch (hptr->type)
  64. {
  65.     case ht_type_spot:
  66. ENUM_RETURN((hptr->params.spot.transfer == 0 ?
  67.          hptr->params.spot.transfer_closure.data :
  68.          0));
  69.     case ht_type_threshold:
  70. ENUM_RETURN_CONST_STRING_PTR(gs_halftone_component,
  71.                  params.threshold.thresholds);
  72.     case ht_type_threshold2:
  73. return ENUM_CONST_BYTESTRING(&hptr->params.threshold2.thresholds);
  74.     case ht_type_client_order:
  75. ENUM_RETURN(hptr->params.client_order.client_data);
  76.     default:            /* not possible */
  77. return 0;
  78. }
  79. case 1:
  80. switch (hptr->type) {
  81.     case ht_type_threshold:
  82.     ENUM_RETURN((hptr->params.threshold.transfer == 0 ?
  83.              hptr->params.threshold.transfer_closure.data :
  84.              0));
  85.     case ht_type_threshold2:
  86.     ENUM_RETURN(hptr->params.threshold2.transfer_closure.data);
  87.     case ht_type_client_order:
  88.     ENUM_RETURN(hptr->params.client_order.transfer_closure.data);
  89.     default:
  90.     return 0;
  91. }
  92. ENUM_PTRS_END
  93. private RELOC_PTRS_WITH(halftone_component_reloc_ptrs, gs_halftone_component *hptr)
  94. {
  95.     switch (hptr->type) {
  96.     case ht_type_spot:
  97.         if (hptr->params.spot.transfer == 0)
  98.         RELOC_VAR(hptr->params.spot.transfer_closure.data);
  99.         break;
  100.     case ht_type_threshold:
  101.         RELOC_CONST_STRING_VAR(hptr->params.threshold.thresholds);
  102.         if (hptr->params.threshold.transfer == 0)
  103.         RELOC_VAR(hptr->params.threshold.transfer_closure.data);
  104.         break;
  105.     case ht_type_threshold2:
  106.         RELOC_CONST_BYTESTRING_VAR(hptr->params.threshold2.thresholds);
  107.         RELOC_OBJ_VAR(hptr->params.threshold2.transfer_closure.data);
  108.         break;
  109.     case ht_type_client_order:
  110.         RELOC_VAR(hptr->params.client_order.client_data);
  111.         RELOC_VAR(hptr->params.client_order.transfer_closure.data);
  112.         break;
  113.     default:
  114.         break;
  115.     }
  116. }
  117. RELOC_PTRS_END
  118.  
  119. /* setcolorscreen */
  120. int
  121. gs_setcolorscreen(gs_state * pgs, gs_colorscreen_halftone * pht)
  122. {
  123.     gs_halftone ht;
  124.  
  125.     ht.type = ht_type_colorscreen;
  126.     ht.params.colorscreen = *pht;
  127.     return gs_sethalftone(pgs, &ht);
  128. }
  129.  
  130. /* currentcolorscreen */
  131. int
  132. gs_currentcolorscreen(gs_state * pgs, gs_colorscreen_halftone * pht)
  133. {
  134.     int code;
  135.  
  136.     switch (pgs->halftone->type) {
  137.     case ht_type_colorscreen:
  138.         *pht = pgs->halftone->params.colorscreen;
  139.         return 0;
  140.     default:
  141.         code = gs_currentscreen(pgs, &pht->screens.colored.gray);
  142.         if (code < 0)
  143.         return code;
  144.         pht->screens.colored.red = pht->screens.colored.gray;
  145.         pht->screens.colored.green = pht->screens.colored.gray;
  146.         pht->screens.colored.blue = pht->screens.colored.gray;
  147.         return 0;
  148.     }
  149. }
  150.  
  151. /* Set the halftone in the graphics state. */
  152. int
  153. gs_sethalftone(gs_state * pgs, gs_halftone * pht)
  154. {
  155.     gs_halftone ht;
  156.  
  157.     ht = *pht;
  158.     ht.rc.memory = pgs->memory;
  159.     return gs_sethalftone_allocated(pgs, &ht);
  160. }
  161. int
  162. gs_sethalftone_allocated(gs_state * pgs, gs_halftone * pht)
  163. {
  164.     gx_device_halftone dev_ht;
  165.     int code = gs_sethalftone_prepare(pgs, pht, &dev_ht);
  166.  
  167.     if (code < 0)
  168.     return code;
  169.     dev_ht.rc.memory = pht->rc.memory;
  170.     return gx_ht_install(pgs, pht, &dev_ht);
  171. }
  172. /* Prepare the halftone, but don't install it. */
  173. int
  174. gs_sethalftone_prepare(gs_state * pgs, gs_halftone * pht,
  175.                gx_device_halftone * pdht)
  176. {
  177.     gs_memory_t *mem = pht->rc.memory;
  178.     gx_ht_order_component *pocs = 0;
  179.     int code = 0;
  180.  
  181.     switch (pht->type) {
  182.     case ht_type_colorscreen:
  183.         {
  184.         gs_screen_halftone *phc =
  185.         pht->params.colorscreen.screens.indexed;
  186.         static const gs_ht_separation_name cnames[4] =
  187.         {
  188.             gs_ht_separation_Default, gs_ht_separation_Red,
  189.             gs_ht_separation_Green, gs_ht_separation_Blue
  190.         };
  191.         static const int cindex[4] =
  192.         {3, 0, 1, 2};
  193.         int i;
  194.  
  195.         pocs = gs_alloc_struct_array(mem, 4,
  196.                          gx_ht_order_component,
  197.                          &st_ht_order_component_element,
  198.                          "gs_sethalftone");
  199.         if (pocs == 0)
  200.             return_error(gs_error_VMerror);
  201.         for (i = 0; i < 4; i++) {
  202.             gs_screen_enum senum;
  203.             int ci = cindex[i];
  204.             gx_ht_order_component *poc = &pocs[i];
  205.  
  206.             code = gx_ht_process_screen_memory(&senum, pgs,
  207.                 &phc[ci], gs_currentaccuratescreens(), mem);
  208.             if (code < 0)
  209.             break;
  210.             poc->corder = senum.order;
  211.             poc->cname = cnames[i];
  212.             if (i == 0)    /* Gray = Default */
  213.             pdht->order = senum.order;
  214.             else {
  215.             uint tile_bytes = senum.order.raster *
  216.                 (senum.order.num_bits / senum.order.width);
  217.             uint num_tiles =
  218.                 max_tile_cache_bytes / tile_bytes + 1;
  219.             gx_ht_cache *pcache =
  220.                 gx_ht_alloc_cache(mem, num_tiles,
  221.                           tile_bytes * num_tiles);
  222.  
  223.             if (pcache == 0) {
  224.                 code = gs_note_error(gs_error_VMerror);
  225.                 break;
  226.             }
  227.             poc->corder.cache = pcache;
  228.             gx_ht_init_cache(pcache, &poc->corder);
  229.             }
  230.         }
  231.         if (code < 0)
  232.             break;
  233.         pdht->components = pocs;
  234.         pdht->num_comp = 4;
  235.         }
  236.         break;
  237.     case ht_type_spot:
  238.         code = process_spot(&pdht->order, pgs, &pht->params.spot, mem);
  239.         if (code < 0)
  240.         return code;
  241.         pdht->components = 0;
  242.         break;
  243.     case ht_type_threshold:
  244.         code = process_threshold(&pdht->order, pgs,
  245.                      &pht->params.threshold, mem);
  246.         if (code < 0)
  247.         return code;
  248.         pdht->components = 0;
  249.         break;
  250.     case ht_type_threshold2:
  251.         code = process_threshold2(&pdht->order, pgs,
  252.                       &pht->params.threshold2, mem);
  253.         if (code < 0)
  254.         return code;
  255.         pdht->components = 0;
  256.         break;
  257.     case ht_type_client_order:
  258.         code = process_client_order(&pdht->order, pgs,
  259.                     &pht->params.client_order, mem);
  260.         if (code < 0)
  261.         return code;
  262.         pdht->components = 0;
  263.         break;
  264.     case ht_type_multiple:
  265.     case ht_type_multiple_colorscreen:
  266.         {
  267.         uint count = pht->params.multiple.num_comp;
  268.         bool have_Default = false;
  269.         uint i;
  270.         gs_halftone_component *phc = pht->params.multiple.components;
  271.         gx_ht_order_component *poc_next;
  272.  
  273.         pocs = gs_alloc_struct_array(mem, count,
  274.                          gx_ht_order_component,
  275.                          &st_ht_order_component_element,
  276.                          "gs_sethalftone");
  277.         if (pocs == 0)
  278.             return_error(gs_error_VMerror);
  279.         poc_next = pocs + 1;
  280.         for (i = 0; i < count; i++, phc++) {
  281.             gx_ht_order_component *poc;
  282.  
  283.             if (phc->cname == gs_ht_separation_Default) {
  284.             if (have_Default) {
  285.                 /* Duplicate Default */
  286.                 code = gs_note_error(gs_error_rangecheck);
  287.                 break;
  288.             }
  289.             poc = pocs;
  290.             have_Default = true;
  291.             } else if (i == count - 1 && !have_Default) {
  292.             /* No Default */
  293.             code = gs_note_error(gs_error_rangecheck);
  294.             break;
  295.             } else
  296.             poc = poc_next++;
  297.             poc->cname = phc->cname;
  298.             switch (phc->type) {
  299.             case ht_type_spot:
  300.                 code = process_spot(&poc->corder, pgs,
  301.                         &phc->params.spot, mem);
  302.                 break;
  303.             case ht_type_threshold:
  304.                 code = process_threshold(&poc->corder, pgs,
  305.                         &phc->params.threshold, mem);
  306.                 break;
  307.             case ht_type_threshold2:
  308.                 code = process_threshold2(&poc->corder, pgs,
  309.                         &phc->params.threshold2, mem);
  310.                 break;
  311.             case ht_type_client_order:
  312.                 code = process_client_order(&poc->corder, pgs,
  313.                         &phc->params.client_order, mem);
  314.                 break;
  315.             default:
  316.                 code = gs_note_error(gs_error_rangecheck);
  317.                 break;
  318.             }
  319.             if (code < 0)
  320.             break;
  321.             if (poc != pocs) {
  322.             gx_ht_cache *pcache =
  323.             gx_ht_alloc_cache(mem, 4,
  324.                       poc->corder.raster *
  325.                       (poc->corder.num_bits /
  326.                        poc->corder.width) * 4);
  327.  
  328.             if (pcache == 0) {
  329.                 code = gs_note_error(gs_error_VMerror);
  330.                 break;
  331.             }
  332.             poc->corder.cache = pcache;
  333.             gx_ht_init_cache(pcache, &poc->corder);
  334.             }
  335.         }
  336.         if (code < 0)
  337.             break;
  338.         pdht->order = pocs[0].corder;    /* Default */
  339.         if (count == 1) {
  340.             /* We have only a Default; */
  341.             /* we don't need components. */
  342.             gs_free_object(mem, pocs, "gs_sethalftone");
  343.             pdht->components = 0;
  344.         } else {
  345.             pdht->components = pocs;
  346.             pdht->num_comp = count;
  347.         }
  348.         }
  349.         break;
  350.     default:
  351.         return_error(gs_error_rangecheck);
  352.     }
  353.     if (code < 0)
  354.     gs_free_object(mem, pocs, "gs_sethalftone");
  355.     return code;
  356. }
  357.  
  358. /* ------ Internal routines ------ */
  359.  
  360. /* Process a transfer function override, if any. */
  361. private int
  362. process_transfer(gx_ht_order * porder, gs_state * pgs,
  363.          gs_mapping_proc proc, gs_mapping_closure_t * pmc,
  364.          gs_memory_t * mem)
  365. {
  366.     gx_transfer_map *pmap;
  367.  
  368.     if (proc == 0 && pmc->proc == 0)
  369.     return 0;
  370.     pmap = gs_alloc_struct(mem, gx_transfer_map, &st_transfer_map,
  371.                "process_transfer");
  372.     if (pmap == 0)
  373.     return_error(gs_error_VMerror);
  374.     pmap->proc = proc;        /* 0 => use closure */
  375.     pmap->closure = *pmc;
  376.     pmap->id = gs_next_ids(1);
  377.     load_transfer_map(pgs, pmap, 0.0);
  378.     porder->transfer = pmap;
  379.     return 0;
  380. }
  381.  
  382. /* Process a spot plane. */
  383. private int
  384. process_spot(gx_ht_order * porder, gs_state * pgs,
  385.          gs_spot_halftone * phsp, gs_memory_t * mem)
  386. {
  387.     gs_screen_enum senum;
  388.  
  389.     int code = gx_ht_process_screen_memory(&senum, pgs, &phsp->screen,
  390.                        phsp->accurate_screens, mem);
  391.  
  392.     if (code < 0)
  393.     return code;
  394.     *porder = senum.order;
  395.     return process_transfer(porder, pgs, phsp->transfer,
  396.                 &phsp->transfer_closure, mem);
  397. }
  398.  
  399. /* Construct the halftone order from a threshold array. */
  400. void
  401. gx_ht_complete_threshold_order(gx_ht_order * porder)
  402. {
  403.     int num_levels = porder->num_levels;
  404.     uint *levels = porder->levels;
  405.     uint size = porder->num_bits;
  406.     gx_ht_bit *bits = porder->bit_data;
  407.     uint i, j;
  408.  
  409.     /* The caller has set bits[i] = max(1, thresholds[i]). */
  410.     gx_sort_ht_order(bits, size);
  411.     /* We want to set levels[j] to the lowest value of i */
  412.     /* such that bits[i].mask > j. */
  413.     for (i = 0, j = 0; i < size; i++) {
  414.     if (bits[i].mask != j) {
  415.         if_debug3('h', "[h]levels[%u..%u] = %u\n",
  416.               j, (uint) bits[i].mask, i);
  417.         while (j < bits[i].mask)
  418.         levels[j++] = i;
  419.     }
  420.     }
  421.     while (j < num_levels)
  422.     levels[j++] = size;
  423.     gx_ht_construct_bits(porder);
  424. }
  425. int
  426. gx_ht_construct_threshold_order(gx_ht_order * porder, const byte * thresholds)
  427. {
  428.     return porder->procs->construct_order(porder, thresholds);
  429. }
  430.  
  431. /* Process a threshold plane. */
  432. private int
  433. process_threshold(gx_ht_order * porder, gs_state * pgs,
  434.           gs_threshold_halftone * phtp, gs_memory_t * mem)
  435. {
  436.     int code;
  437.  
  438.     porder->params.M = phtp->width, porder->params.N = 0;
  439.     porder->params.R = 1;
  440.     porder->params.M1 = phtp->height, porder->params.N1 = 0;
  441.     porder->params.R1 = 1;
  442.     code = gx_ht_alloc_threshold_order(porder, phtp->width, phtp->height,
  443.                        256, mem);
  444.     if (code < 0)
  445.     return code;
  446.     gx_ht_construct_threshold_order(porder, phtp->thresholds.data);
  447.     return process_transfer(porder, pgs, phtp->transfer,
  448.                 &phtp->transfer_closure, mem);
  449. }
  450.  
  451. /* Process an extended threshold plane. */
  452. private int
  453. process_threshold2(gx_ht_order * porder, gs_state * pgs,
  454.            gs_threshold2_halftone * phtp, gs_memory_t * mem)
  455. {
  456.     int code;
  457.     /*
  458.      * There are potentially 64K different levels for this plane, but this
  459.      * is more than we're willing to handle.  Try to reduce the number of
  460.      * levels by dropping leading or trailing zero bits from the thresholds;
  461.      * as a last resort, drop (possibly significant) trailing bits.
  462.      */
  463. #define LOG2_MAX_HT_LEVELS 14
  464. #define MAX_HT_LEVELS (1 << LOG2_MAX_HT_LEVELS)
  465.     int bps = phtp->bytes_per_sample;
  466.     const byte *data = phtp->thresholds.data;
  467.     const int w1 = phtp->width, h1 = phtp->height, size1 = w1 * h1;
  468.     const int w2 = phtp->width2, h2 = phtp->height2, size2 = w2 * h2;
  469.     const uint size = size1 + size2;
  470.     const int d = (h2 == 0 ? h1 : igcd(h1, h2));
  471.     const int sod = size / d;
  472.     uint num_levels;
  473.     uint i;
  474.     int rshift = 0;
  475.     int shift;
  476.  
  477.     {
  478.     uint mask = 0, max_thr = 0;
  479.  
  480.     for (i = 0; i < size; ++i) {
  481.         uint thr =
  482.         (bps == 1 ? data[i] : (data[i * 2] << 8) + data[i * 2 + 1]);
  483.  
  484.         mask |= thr;
  485.         max_thr = max(max_thr, thr);
  486.     }
  487.     if (mask == 0)
  488.         mask = 1, max_thr = 1;
  489.     while (!(mask & 1) || max_thr > MAX_HT_LEVELS)
  490.         mask >>= 1, max_thr >>= 1, rshift++;
  491.     num_levels = max_thr + 1;
  492.     }
  493.     /*
  494.      * Set nominal values for the params, and don't bother to call
  495.      * gx_compute_cell_values -- the values are only needed for spot
  496.      * halftones.
  497.      */
  498.     porder->params.M = sod, porder->params.N = d;
  499.     porder->params.R = 1;
  500.     porder->params.M1 = d, porder->params.N1 = sod;
  501.     porder->params.R1 = 1;
  502.     /*
  503.      * Determine the shift between strips.  We don't know a closed formula
  504.      * for this, so we do it by enumeration.
  505.      */
  506.     shift = 0;
  507.     {
  508.     int x = 0, y = 0;
  509.  
  510.     do {
  511.         if (y < h1)
  512.         x += w1, y += h2;
  513.         else
  514.         x += w2, y -= h1;
  515.     } while (y > d);
  516.     if (y)
  517.         shift = x;
  518.     }
  519.     code = gx_ht_alloc_ht_order(porder, sod, d, num_levels, size, shift,
  520.                 &ht_order_procs_default, mem);
  521.     if (code < 0)
  522.     return code;
  523.     {
  524.     gx_ht_bit *bits = (gx_ht_bit *)porder->bit_data;
  525.     int row, di;
  526.  
  527.     if_debug7('h', "[h]rect1=(%d,%d), rect2=(%d,%d), strip=(%d,%d), shift=%d\n",
  528.           w1, h1, w2, h2, sod, d, shift);
  529.     for (row = 0, di = 0; row < d; ++row) {
  530.         /* Iterate over destination rows. */
  531.         int dx, sy = row;    /* sy = row mod d */
  532.         int w;
  533.  
  534.         for (dx = 0; dx < sod; dx += w) {
  535.         /* Iterate within a destination row, over source rows. */
  536.         int si, j;
  537.  
  538.         if (sy < h1) {
  539.             /* Copy a row from rect1. */
  540.             si = sy * w1;
  541.             w = w1;
  542.             sy += h2;
  543.         } else {
  544.             /* Copy a row from rect2. */
  545.             si = size1 + (sy - h1) * w2;
  546.             w = w2;
  547.             sy -= h1;
  548.         }
  549.         for (j = 0; j < w; ++j, ++si, ++di) {
  550.             uint thr =
  551.             (bps == 1 ? data[si] :
  552.              (data[si * 2] << 8) + data[si * 2 + 1])
  553.                        >> rshift;
  554.  
  555.             if_debug3('H', "[H]sy=%d, si=%d, di=%d\n", sy, si, di);
  556.             bits[di].mask = max(thr, 1);
  557.         }
  558.         }
  559.     }
  560.     }
  561.     gx_ht_complete_threshold_order(porder);
  562.     return process_transfer(porder, pgs, NULL, &phtp->transfer_closure, mem);
  563. #undef LOG2_MAX_HT_LEVELS
  564. #undef MAX_HT_LEVELS
  565. }
  566.  
  567. /* Process a client-order plane. */
  568. private int
  569. process_client_order(gx_ht_order * porder, gs_state * pgs,
  570.              gs_client_order_halftone * phcop, gs_memory_t * mem)
  571. {
  572.     int code = (*phcop->procs->create_order) (porder, pgs, phcop, mem);
  573.  
  574.     if (code < 0)
  575.     return code;
  576.     return process_transfer(porder, pgs, NULL,
  577.                 &phcop->transfer_closure, mem);
  578. }
  579.